import { ComputedRef } from 'vue';
/* api */
import { getCardRelationPaasApplicationList } from '@src/modules/connector/api'
/* model */
import { ConnectorCardInfo, ConnectorCardInfoConfig, ConnectorModuleErrorMessageEnum } from '@src/modules/connector/model'
import MsgModel from '@model/MsgModel'
/* hooks */
import { useLoading } from '@hooks/useLoading'
/* util */
import { message } from '@src/util/message'
import { isFalsy, isObject, isString, isUndefined } from '@src/util/type'
import { parse } from '@src/util/lang/object'
import Log from '@src/util/log'
/* vue */
import { computed } from 'vue'

/**
 * @description 获取附件组件可以关联的应用列表
 */
function useFetchCardRelationPaasApplicationList() {
  
  const { loading, setLoading, clearLoading } = useLoading()
  
  const fetchCardRelationPaasApplicationList = (params: any) => {
    
    setLoading()
    
    return (
      getCardRelationPaasApplicationList(params).then(result => {
        
        if (MsgModel.isSuccess(result)) {
          
          const relationPaasApplicationList = result?.data || []
          
          return relationPaasApplicationList
          
        } else {
          
          message.error(result?.message || ConnectorModuleErrorMessageEnum.CardRelationPaasApplicationList)
          
          return []
        }
        
      })
      .catch(error => {
        
        message.error(ConnectorModuleErrorMessageEnum.CardRelationPaasApplicationList)
        
        Log.error(error, fetchCardRelationPaasApplicationList.name)
        
        return []
        
      })
      .finally(() => {
        
        clearLoading()
        
      })
    )
  }
  
  return {
    loading,
    fetchCardRelationPaasApplicationList
  }
}

function useConnectorCard(props: { card: ConnectorCardInfo, mainModuleValue: Record<string, any> }) {
  
  const card: ComputedRef<ConnectorCardInfo> = computed(() => props?.card || {})
  
  const state: ComputedRef<string> = computed(() => props?.mainModuleValue?.state)
  
  const { canExport, canCreate, canEdit, canDelete } = useConnectorCardAuth(card, state)
  
  return {
    canExport,
    canCreate,
    canEdit,
    canDelete
  }
}

function useConnectorCardAuth(card: ComputedRef<ConnectorCardInfo>, state: ComputedRef<string>) {
  
  /** 
   * 是否支持工单附加组件导出
  */
  const canExport = useConnectorCardAuthCanExport(card)
  
  /** 
   * 是否为 旧附加组件权限
  */
  const isOldAuth = useConnectorCardAuthIsOld(card)
  
  /** 
   * 是否支持 编辑附加组件
  */
  const stateCanEdit = useConnectorCardAuthStateCanEdit(card, state)
  
  /** 
   * 是否支持 新增附加组件
  */
  const canCreate = useConnectorCardAuthCanCreate(card, state)
  
  /** 
   * 是否支持 编辑附件组件
  */
  const canEdit = useConnectorCardAuthCanEdit(card, state)
  
  /** 
   * 是否支持 删除附加组件
  */
  const canDelete = useConnectorCardAuthCanDelete(card, state)
  
  return {
    canExport,
    canCreate,
    canEdit,
    canDelete
  }
}

/** 
 * @description 连接器附加组件权限 是否为旧权限
 * 只有两个权限，没有返回 canCreate 以及 canDelete
*/
function useConnectorCardAuthIsOld(card: ComputedRef<ConnectorCardInfo>) {
  return computed(() => {
    try {
      
      let { canCreate, canDelete } = card.value
      
      return isUndefined(canCreate) && isUndefined(canDelete)
      
    } catch (error) {
      
      Log.error(error, useConnectorCardAuthIsOld.name)
      
      return false
      
    }
  })
}

/** 
  * @description 连接器附加组件 是否支持工单附加组件导出
*/
function useConnectorCardAuthCanExport(card: ComputedRef<ConnectorCardInfo>) {
  return computed(() => {
    try {
      
      const config = card.value.config
      
      if (isString(config)) {
        
        const configObject = parse(config as unknown as string)
        
        return Boolean(configObject?.export)
      }
      
      if (isObject(config)) {
        return Boolean((config as ConnectorCardInfoConfig)?.export)
      }
      
      return false
      
    } catch (error) {
      
      Log.error(error, useConnectorCardAuthCanExport.name)
      
      return false
      
    }
  })
}

/** 
  * @description 连接器附加组件 是否允许 新增
  * -- 1. 有新增权限 或者 老权限(无新增和删除) 且 有编辑权限
  * -- 2. 附加组件设置的允许某种状态下可编辑 或 无设置
  * 
*/
function useConnectorCardAuthCanCreate(card: ComputedRef<ConnectorCardInfo>, state: ComputedRef<string>) {
  
  /** 
   * 是否为 旧附加组件权限
  */
  const isOldAuth = useConnectorCardAuthIsOld(card)
  
  /** 
   * 是否支持 编辑附加组件
  */
  const stateCanEdit = useConnectorCardAuthStateCanEdit(card, state)
  
  return computed(() => {
    try {
      
      let { canCreate, canWrite } = card.value
      
      // 1. 有新增权限 或者 老权限(无新增和删除) 且 有编辑权限
      let createAuth = canCreate || (isOldAuth.value && canWrite)
      
      // 2. 附加组件设置的允许某种状态下可编辑 或 无设置
      let stateAllowEdit = stateCanEdit.value
      
      return Boolean(createAuth && stateAllowEdit)
      
    } catch (error) {
      
      Log.error(error, useConnectorCardAuthCanCreate.name)
      
      return false
      
    }
  })
}

/** 
  * @description 连接器附加组件 是否允许 删除
  * -- 1. 有删除权限 或者 老权限(无新增和删除) 且 有编辑权限
  * -- 2. 附加组件设置的允许某种状态下可编辑 或 无设置
  * 
*/
function useConnectorCardAuthCanDelete(card: ComputedRef<ConnectorCardInfo>, state: ComputedRef<string>) {
  
  /** 
   * 是否为 旧附加组件权限
  */
  const isOldAuth = useConnectorCardAuthIsOld(card)
  
  /** 
   * 是否支持 编辑附加组件
  */
  const stateCanEdit = useConnectorCardAuthStateCanEdit(card, state)
  
  return computed(() => {
    try {
      
      let { canDelete, canWrite } = card.value
      
      // 1. 有删除权限 或者 老权限(无新增和删除) 且 有编辑权限
      let deleteAuth = canDelete || (isOldAuth.value && canWrite)
      
      // 2. 附加组件设置的允许某种状态下可编辑 或 无设置
      let stateAllowEdit = stateCanEdit.value
      
      return Boolean(deleteAuth && stateAllowEdit)
      
    } catch (error) {
      
      Log.error(error, useConnectorCardAuthCanDelete.name)
      
      return false
      
    }
  })
}

/** 
  * @description 连接器附加组件 当前状态是否允许 编辑
  * 
*/
function useConnectorCardAuthStateCanEdit(card: ComputedRef<ConnectorCardInfo>, state: ComputedRef<string>) {
  return computed(() => {
    try {
      
      // 该附加组件设置处于某种状态下可以编辑
      const stateCanEdit = card.value.stateCanEdit
      
      // 没有设置则默认可以编辑
      if (isFalsy(stateCanEdit) || isFalsy(stateCanEdit?.length)) {
        return true
      }
      
      // 如果设置了，则判断设置的节点是否包含当前工单状态
      return (stateCanEdit as string[]).includes(state.value)
      
    } catch (error) {
      
      Log.error(error, useConnectorCardAuthStateCanEdit.name)
      
      return false
      
    }
  })
}

/** 
  * @description 连接器附加组件 当前状态是否允许 编辑
  * 
*/
function useConnectorCardAuthCanEdit(card: ComputedRef<ConnectorCardInfo>, state: ComputedRef<string>) {
  
  /** 
   * 当前状态是否支持 编辑附加组件
  */
  const stateCanEdit = useConnectorCardAuthStateCanEdit(card, state)
  
  return computed(() => {
    try {
      
      const canWrite = card.value.canWrite
      
      return Boolean(stateCanEdit.value && canWrite)
      
    } catch (error) {
      
      Log.error(error, useConnectorCardAuthCanEdit.name)
      
      return false
      
    }
  })
}

export {
  useConnectorCard,
  useFetchCardRelationPaasApplicationList
}
